﻿using System;
using System.Data;
using System.Data.Common;
using System.Data.SQLite;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using LumenWorks.Framework.IO.Csv; 

namespace estiglp1112_5479_csharp_rec
{
    /**
     * Data: 24/02/2012
     * Autor: João Vitor Machado Batista Nº 5479
     */
    class statistics
    {
        const string dataSource = "Data Source = ..\\..\\database\\rebides.db";

        /**
         * Este método vai buscar à bd uma lista de escolas referentes a um ano
         * 
         * @param year ano escolhido pelo utilizador na interface
         */
        public List<string> escolasDoAno(int year)
        {
            //abre a ligação à base de dados
            SQLiteConnection conn = new SQLiteConnection(dataSource);
            conn.Open();
            SQLiteTransaction trans = conn.BeginTransaction();
            SQLiteCommand cmd = conn.CreateCommand();

            string getData = string.Format("SELECT * FROM data_{0}", year);

            cmd.CommandText = getData;

            DbDataReader reader = cmd.ExecuteReader();

            //apenas vou buscar as escolas
            List<string> data = new List<string>();
            while (reader.Read())
            {
                data.Add(reader.GetString(8));
            }

            conn.Close();

            //através do linq selecciona as diferentes escolas
            var escolasVar = data.Distinct();

            //cria uma lista de strings com as escolas
            List<string> escolas = new List<string>();
            foreach (string escola in escolasVar)
            {
                escolas.Add(escola);
            }
            
            //ordena as escolas
            escolas.Sort();

            return escolas;
        }

        /**
         * Este método calcula a estatistica 1, ou seja, o nº de escolas por ano
         */
        public List<string> stat1()
        {
            // lista que vai guardar os resultados do método para ser mostrada na interface
            List<string> resultados = new List<string>();

            //calcula para cada ano o nº de escolas
            for (int year = 2000; year < 2011; year++)
            {
                //primeira versão

                    ////ligação à base de dados
                    //SQLiteConnection conn = new SQLiteConnection("Data Source = ..\\..\\database\\rebides.db");
                    //conn.Open();
                    //SQLiteTransaction trans = conn.BeginTransaction();
                    //SQLiteCommand cmd = conn.CreateCommand();

                    //string getData = string.Format("SELECT * FROM data_{0}", year);
                    //cmd.CommandText = getData;

                    ////novamente vai buscar as escolas
                    //DbDataReader reader = cmd.ExecuteReader();
                    //List<string> data = new List<string>();
                    //while (reader.Read())
                    //{
                    //    data.Add(reader.GetString(8));
                    //}

                    //conn.Close();

                    //int valor = data.Distinct().Count();
                
                //segunda versão, utiliza o metodo criado para preencher a combobox com as escolas criado para a 3ª
                //estatistica
                List<string> escolas = this.escolasDoAno(year); 
                int valor = escolas.Count();

                string resultado = string.Format("No ano {0} existiam {1} escolas!\n", year, valor);

                resultados.Add(resultado);
                
            }

            return resultados;
        }

        /**
         * Este método calcula a estatistica 2, ou seja, o nº de professores por categoria num ano
         * Decidi fazer apenas para um ano de cada vez para não ficar uma lista muito grande na interface.
         * 
         * @param year ano escolhido pelo utilizador na interface
         */
        public List<string> stat2(int year)
        {
            //lista de strings que vai mostrar os resultados na interface
            List<string> resultados = new List<string>();
            string anoR = string.Format("Ano: {0}\n", year);
            resultados.Add(anoR);
            
            //ligação à bd
            SQLiteConnection conn = new SQLiteConnection(dataSource);
            conn.Open();
            SQLiteTransaction trans = conn.BeginTransaction();
            SQLiteCommand cmd = conn.CreateCommand();

            string getData = string.Format("SELECT * FROM data_{0}", year);
            cmd.CommandText = getData;

            DbDataReader reader = cmd.ExecuteReader();
            
            //através de um array de duas dimensões vou buscar os professores e as categorias
            //guarda também uma lista temporaria com as categorias existentes no ano
            List<String[,]> data = new List<String[,]>();
            List<string> categoriasTemp = new List<string>();
            while(reader.Read())
            {
                string[,] s = { {reader.GetString(1), reader.GetString(4)} };
                data.Add(s);
                categoriasTemp.Add(reader.GetString(4));
            }

            conn.Close();

            //cria uma lista com as categorias ordenadas
            var categoriasVar = categoriasTemp.Distinct();
            List<string> categoriasFinal = new List<string>();
            foreach (string categoria in categoriasVar)
            {
                categoriasFinal.Add(categoria);
            }
            categoriasFinal.Sort();

            //calcula a estatistica para cada categoria do ano
            foreach (string categoria in categoriasFinal)
            {
                //[0, 1]-> onde está guardada a categoria
                //[0, 0]-> os nomes dos professores
                var profs =
                    from linha in data
                    where linha[0, 1].Equals(categoria)
                    select linha[0, 0];

                //remove os professores repetidos
                int valor = profs.Distinct().Count();

                string resultado = string.Format("Categoria: {0} | Nº professores: {1}!\n",categoria, valor);

                resultados.Add(resultado);
            }

            return resultados;
        }

        /**
         * Este método calcula a estatistica 3, ou seja, o nº de professores por categoria 
         * numa determinada escola e ano.
         * Como o método é praticamente igual ao anterior apenas as diferença estão comentadas
         * Decidi fazer apenas para um ano e escola de cada vez para não ficar uma lista muito grande na interface.
         * 
         * @param year ano escolhido pelo utilizador na interface
         * @param escola escola escolhida pelo utilizador na interface
         */
        public List<string> stat3(int year, string escola)
        {
            List<string> resultados = new List<string>();
            string anoR = string.Format("Ano: {0}\n", year);
            resultados.Add(anoR);
            string escolaR = string.Format("Escola: {0}\n", escola);
            resultados.Add(escolaR);

            SQLiteConnection conn = new SQLiteConnection(dataSource);
            conn.Open();
            SQLiteTransaction trans = conn.BeginTransaction();
            SQLiteCommand cmd = conn.CreateCommand();

            string getData = string.Format("SELECT * FROM data_{0}", year);

            cmd.CommandText = getData;

            List<String[,]> data = new List<String[,]>();
            List<string> categoriasTemp = new List<string>();
            DbDataReader reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                string[,] s = new string[1, 3] { { reader.GetString(1), reader.GetString(4), reader.GetString(8)} };
                data.Add(s);
                categoriasTemp.Add(reader.GetString(4));
            }

            conn.Close();

            var categoriasVar = categoriasTemp.Distinct();
            List<string> categoriasFinal = new List<string>();
            foreach (string categoria in categoriasVar)
            {
                categoriasFinal.Add(categoria);
            }
            categoriasFinal.Sort();

            //desta vez é verificada a categoria e a escola
            foreach (string categoria in categoriasFinal)
            {
                var profs =
                    from array in data
                    where array[0, 1].Equals(categoria) && array[0, 2].Equals(escola)
                    select array[0, 0];

                int valor = profs.Distinct().Count();

                //apenas vai mostrar os resultados para os quais tem valores pois nem todas as categorias
                //estão presentes na escola em questão
                if (valor != 0)
                {
                    string resultado = string.Format("Categoria: {0} | Nº professores: {1}!\n", categoria, valor);
                    resultados.Add(resultado);
                }
            }

            return resultados;
        }

    }
}
